package com.web4code.codegen.generator;

import java.io.File;
import java.io.IOException;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.List;

import com.web4code.codegen.config.GenConfig;
import com.web4code.codegen.constant.Constants;
import com.web4code.codegen.domain.GenTable;
import com.web4code.codegen.importer.FileImporter;
import com.web4code.codegen.utils.StringUtils;

import org.apache.commons.io.FileUtils;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.Velocity;

/**
 * 代码生成主逻辑-表格代码生成
 * 
 * @author web4code
 */
public class GeneratorUtils {
    /**
     * 生成代码
     * @throws IOException
     */
    public static boolean generatorCodeAll() throws IOException
    {
        final List<GenTable> genTableList = new ArrayList<GenTable>();
        final GenConfig genConfig = GenConfig.getGenConfig();
        final String dateType = genConfig.getDataSourceType();
        if (StringUtils.equals(dateType, "local")) {
            File directory = new File(genConfig.getDataSourceParam());
            File flist[] = directory.listFiles();
            for (File f : flist) {
                if (f.isFile() && f.getName().startsWith("table")) {
                    final String fullFilePath = genConfig.getDataSourceParam() + File.separator + f.getName();
                    GenTable genTable = FileImporter.importFile(fullFilePath, GenTable.class);
                    if (genTable != null) {
                        genTableList.add(genTable);
                    }
                }
            }
        }
        else {
            // GenTable table = genTableMapper.selectGenTableByName(tableName);
        }
        //
        generatorCode(genTableList);
        return true;
    }

    /**
     * 生成代码
     * @param table 业务表信息
     * @throws IOException
     */
    public static void generatorCode(List<GenTable> list) throws IOException
    {
        for (GenTable table : list)
        {
            generatorCode(table);
        }
    }

    /**
     * 生成代码
     * @param table 业务表信息
     * @throws IOException
     */
    public static void generatorCode(GenTable table) throws IOException
    {
        VelocityInitializer.initVelocity();

        VelocityContext context = VelocityUtils.prepareContext(table);

        // 获取模板列表
        List<String> templates = VelocityUtils.getTemplateList(table.getTplCategory());
        for (String template : templates)
        {
            if (!StringUtils.containsAny(template, "sql.vm", "api.js.vm", "index.vue.vm", "index-tree.vue.vm"))
            {
                // 渲染模板
                StringWriter sw = new StringWriter();
                final String tplPath = getTplPath(table, template);
                Template tpl = Velocity.getTemplate(tplPath, Constants.UTF8);
                tpl.merge(context, sw);
                try
                {
                    final String path = getGenPath(table, template);
                    FileUtils.writeStringToFile(new File(path), sw.toString(), Constants.UTF8);
                }
                catch (IOException e)
                {
                    throw new IOException("渲染模板失败，表名：" + table.getTableName());
                }
            }
        }
    }

    /**
     * 获取代码模板地址
     * 
     * @param table 业务表信息
     * @param template 模板文件路径
     * @return 模板地址
     */
    private static String getTplPath(GenTable table, String template)
    {
        final String tplPath = table.getTemplatePath();
        if (StringUtils.isEmpty(tplPath)) {
            GenConfig genConfig = GenConfig.getGenConfig();
            return genConfig.getTemplatePath() + File.separator + template;
        }
        return table.getTemplatePath() + File.separator + template;
    }

    /**
     * 获取代码生成地址
     * 
     * @param table 业务表信息
     * @param template 模板文件路径
     * @return 生成地址
     */
    private static String getGenPath(GenTable table, String template)
    {
        String genPath = table.getGenPath();
        if (StringUtils.isEmpty(genPath)) {
            GenConfig genConfig = GenConfig.getGenConfig();
            return genConfig.getGeneratePath() + File.separator + VelocityUtils.getFileName(template, table);
        }
        if (StringUtils.equals(genPath, "/"))
        {
            return System.getProperty("user.dir") + File.separator + "src" + File.separator + VelocityUtils.getFileName(template, table);
        }
        return genPath + File.separator + VelocityUtils.getFileName(template, table);
    }
}
